package ar.edu.utn.frgp.TPFinalBanco.action;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import ar.edu.utn.frgp.TPFinalBanco.model.AcreditacionEnum;
import ar.edu.utn.frgp.TPFinalBanco.model.Cliente;
import ar.edu.utn.frgp.TPFinalBanco.model.Cuenta;
import ar.edu.utn.frgp.TPFinalBanco.model.Movimiento;
import ar.edu.utn.frgp.TPFinalBanco.model.OrigenDineroEnum;
import ar.edu.utn.frgp.TPFinalBanco.model.OrigenMovEnum;
import ar.edu.utn.frgp.TPFinalBanco.model.PlazoFijo;
import ar.edu.utn.frgp.TPFinalBanco.model.TipoCuentaEnum;
import ar.edu.utn.frgp.TPFinalBanco.model.TipoMovimientoEnum;
import ar.edu.utn.frgp.TPFinalBanco.service.impl.GestionClienteServiceImpl;
import ar.edu.utn.frgp.TPFinalBanco.service.impl.GestionCuentaServiceImpl;
import ar.edu.utn.frgp.TPFinalBanco.service.impl.GestionMovimientosServiceImpl;
import ar.edu.utn.frgp.TPFinalBanco.service.impl.GestionPlazoFijoServiceImpl;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.validator.annotations.RegexFieldValidator;
import com.opensymphony.xwork2.validator.annotations.EmailValidator;
import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
import com.opensymphony.xwork2.validator.annotations.ValidatorType;

public class AltaPlazoFijoAction extends BaseAction {

	private static final long serialVersionUID = 1L;
	
	private Cliente cliente;
	private String plazo;
	private BigDecimal montoPZ;
	private Date fechaAlta;
	private Date fechaVenc;
	private String cuentaOrigen;
	private String cuentaDestino;
	private String tipoOrigen;
	private String tipoDestino;
	private PlazoFijo plazofijo;
	private BigDecimal interes;

	public String execute() throws Exception {

		setPlazofijo(new PlazoFijo());
		setFechaAlta(new Date());
		Calendar c = Calendar.getInstance();
		c.setTime(fechaAlta);
		

		
		switch (new Integer(plazo)) {
		case 30:
			c.add(Calendar.DATE, 30);
			setInteres(new BigDecimal(0.10));
			break;
		case 60:
			c.add(Calendar.DATE, 60);
			setInteres(new BigDecimal(0.12));
			break;
		case 90:
			c.add(Calendar.DATE, 90);
			setInteres(new BigDecimal(0.13));
			break;
		}
		fechaVenc = c.getTime();
		Cliente cliente = (Cliente) ActionContext.getContext().getSession()
				.get("cliente");

		plazofijo.setDni(cliente.getDni());
		plazofijo.setFechaAlta(fechaAlta);

		

		plazofijo.setFechaVto(fechaVenc);
		plazofijo.setInteres(montoPZ.multiply(interes));
		plazofijo.setMonto(montoPZ);
		plazofijo.setNroCtaOrigen(new Integer(cuentaOrigen));
		plazofijo.setNroCtaDestino(new Integer(cuentaDestino));
		
		if (tipoOrigen.equals(OrigenDineroEnum.E.getCodigo())) {
			plazofijo.setOrigen(OrigenDineroEnum.E);
		} else {
			plazofijo.setOrigen(OrigenDineroEnum.C);
		}

		if (tipoDestino.equals(AcreditacionEnum.CJ.getCodigo())) {
			plazofijo.setAcreditacion(AcreditacionEnum.CJ);
		} else {
			plazofijo.setAcreditacion(AcreditacionEnum.CT);
		}

		// Obtenemos la cuenta a la cual se va a extraer el dinero
		GestionCuentaServiceImpl cuentaService = (GestionCuentaServiceImpl) getContext()
				.getBean("gestionCuentasService");
		Cuenta cuenta = cuentaService.getCuenta(Integer.parseInt(cuentaOrigen));

		BigDecimal monto = montoPZ;

		if (((cuenta.getSaldo().add(cuenta.getDescubierto())).compareTo(monto) >= 0)
				|| tipoOrigen.equals(OrigenDineroEnum.E.getCodigo())) {
			BigDecimal saldoActual = cuenta.getSaldo();
			if (!tipoOrigen.equals(OrigenDineroEnum.E.getCodigo())) {
				saldoActual = cuenta.getSaldo().subtract(monto);
			}
			// Genero el movimiento y lo agrego en la BD
			Movimiento movimiento = new Movimiento(cuenta, new Date(),
					TipoMovimientoEnum.E, OrigenMovEnum.PF, saldoActual, monto);
			GestionMovimientosServiceImpl movimientosService = (GestionMovimientosServiceImpl) getContext()
					.getBean("gestionMovimientosService");
			movimientosService.createMovimiento(movimiento);

			// Actualizo el saldo de la cuenta y lo guardo en la BD
			cuenta.setSaldo(saldoActual);
			cuentaService.updateCuenta(cuenta);

			// Actualizo la cuenta en la sesión
			List<Cuenta> cuentas = cliente.getCuentas();

			for (Cuenta cuentaCliente : cuentas) {
				if (cuentaCliente.getNroCuenta().equals(cuenta.getNroCuenta())) {
					cuentaCliente.setSaldo(saldoActual);
				}
			}

			cliente.setCuentas(cuentas);
			
			ActionContext.getContext().getSession().put("cliente", cliente);

			GestionPlazoFijoServiceImpl plazoFijoService = (GestionPlazoFijoServiceImpl) getContext()
					.getBean("gestionPlazoFijoService");
			plazoFijoService.savePlazoFijo(plazofijo);

			return SUCCESS;

		} else {
			addActionError("No posee dinero suficiente para extraer ese monto, por favor ingrese un monto menor.");
			cliente = (Cliente) ActionContext.getContext().getSession()
					.get("cliente");
			ActionContext.getContext().getSession().put("cliente", cliente);

			return ERROR;
		}
	}

	public Date getFechaVenc() {
		return fechaVenc;
	}

	public void setFechaVenc(Date fechaVenc) {
		this.fechaVenc = fechaVenc;
	}

	public BigDecimal getMontoPZ() {
		return montoPZ;
	}

	public void setMontoPZ(BigDecimal montoPZ) {
		this.montoPZ = montoPZ;
	}

	public String getPlazo() {
		return plazo;
	}

	public void setPlazo(String plazo) {
		this.plazo = plazo;
	}

	public Date getFechaAlta() {
		return fechaAlta;
	}

	public void setFechaAlta(Date fechaAlta) {
		this.fechaAlta = fechaAlta;
	}

	public String getCuentaOrigen() {
		return cuentaOrigen;
	}

	public void setCuentaOrigen(String cuentaOrigen) {
		this.cuentaOrigen = cuentaOrigen;
	}

	public String getCuentaDestino() {
		return cuentaDestino;
	}

	public void setCuentaDestino(String cuentaDestino) {
		this.cuentaDestino = cuentaDestino;
	}

	public PlazoFijo getPlazofijo() {
		return plazofijo;
	}

	public void setPlazofijo(PlazoFijo plazofijo) {
		this.plazofijo = plazofijo;
	}

	public BigDecimal getInteres() {
		return interes;
	}

	public void setInteres(BigDecimal interes) {
		this.interes = interes;
	}

	public String getTipoOrigen() {
		return tipoOrigen;
	}

	public void setTipoOrigen(String tipoOrigen) {
		this.tipoOrigen = tipoOrigen;
	}

	public String getTipoDestino() {
		return tipoDestino;
	}

	public void setTipoDestino(String tipoDestino) {
		this.tipoDestino = tipoDestino;
	}

	public Cliente getCliente() {
		return cliente;
	}

	public void setCliente(Cliente cliente) {
		this.cliente = cliente;
	}

}
